package com.xinxi11.project.qx.services.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xinxi11.module.core.dao.Finder;
import com.xinxi11.module.core.service.BaseServiceImpl;
import com.xinxi11.project.qx.beans.QxModule;
import com.xinxi11.project.qx.beans.QxRole;
import com.xinxi11.project.qx.beans.QxreRoleModule;
import com.xinxi11.project.qx.services.IQxModuleService;
import com.xinxi11.project.qx.services.IQxRoleService;
import com.xinxi11.project.qx.user.LoginUserUtils;

@Service("qxModuleService")
public class QxModuleServiceImpl extends BaseServiceImpl implements IQxModuleService {

	private final static String sql_all_moduleIds_by_userId = "select re.moduleId from qxre_role_module as re,qx_role as role,qx_module as module where module.id=re.moduleId and re.roleId=role.id and re.roleId in (select roleId from qxre_duty_role where active=0 and dutyId in (select DutyID from Re_User_Duty where UserID=:userId) union select roleId from qxre_user_role where active=0 and userId=:userId1) and (role.endDate is null or role.endDate >= GETDATE()) and module.desplay=2 and re.active=0";
	private IQxRoleService roleService;

	@Autowired
	public void setRoleService(IQxRoleService roleService) {
		this.roleService = roleService;
	}

	@Override
	public JSONObject findArrayJonsModulePageLiknByUserId(Long userId) {
		// 根据人员查询定义的自定义链接模块
		Finder finder = new Finder(
				"select module from QxPageLink as link,QxModule as module where link.userId=:userId and link.moduleId=module.id and module.active=0");
		finder.setParam("userId", userId);
		List<QxModule> linkModules = baseDao.queryForList(finder, null);
		if (CollectionUtils.isEmpty(linkModules))
			return null;
		return createModuleTree(linkModules);
	}

	// 根据list创建模块树
	public JSONObject createModuleTree(List<QxModule> linkModules) {
		JSONObject json = new JSONObject();
		JSONObject attributes = new JSONObject();
		attributes.put("id", -1);
		attributes.put("name", "快速链接");
		json.put("attr", attributes);
		json.put("data", "快速链接");
		json.put("children", GenerateJsonArrayByQxModules(linkModules));
		return json;
	}

	@Override
	public JSONArray findArrayJonsModuleByUserId(Long userId) {
		// 根据角色集合查询模块集合信息
		List<QxModule> qxModules = findModuleByUserId(userId);
		return GenerateJsonArrayByQxModules(qxModules);
	}

	@Override
	public JSONArray findArrayJsonModuleByRoleId(String roleId) {
		if (StringUtils.isEmpty(roleId))
			return null;
		List<String> roleIds = new ArrayList<String>();
		roleIds.add(roleId);
		// 根据角色集合查询模块集合信息
		List<QxModule> qxModules = findArrayJonsModuleByUserId(roleIds);
		return GenerateJsonArrayByQxModules(qxModules);
	}

	@Override
	public JSONArray findArrayJsonQxModuleByRoleIdModuleId(String roleId, String moduleId, boolean flag, Integer display) {
		List<QxModule> qxModules = null;//qxreRoleModuleService.findQxModuleByRoleIdModuleId(roleId, moduleId, flag, display);
		// 把模块封装成模块树
		return GenerateJsonArrayByQxModules(qxModules);
	}

	@Override
	public JSONArray findArrayJonsModuleByModuleId(String moduleId, Integer display) {
		// 根据模块Id查询模块下的所有子模块（包含父模块）
		List<QxModule> qxModules = findChildrenModuleByModuleId(moduleId, display);
		// 把模块封装成模块树
		return GenerateJsonArrayByQxModules(qxModules);
	}

	// /////////////////////////////////////////////////////////生成树数据Json
	// Start///////////////////////////////////////////
	/**
	 * 根据模块生成模块JsonArray数组
	 * 
	 * @param qxModules
	 * @return
	 */
	private JSONArray GenerateJsonArrayByQxModules(List<QxModule> qxModules) {
		if (CollectionUtils.isEmpty(qxModules))
			return null;
		// 获取最顶的模块集合
		List<QxModule> djModules = findLastSameLevelModules(qxModules);
		// 封装JSONObject对象
		return moduleChildTreeNode(djModules, qxModules);
	}

	/**
	 * 封装JsonArray数组
	 * 
	 * @param qxModules
	 */
	private JSONArray moduleChildTreeNode(List<QxModule> childModules, List<QxModule> qxModuleList) {
		JSONArray jsonArray = new JSONArray();
		if (childModules != null && childModules.size() > 0) {
			for (QxModule module : childModules) {
				jsonArray.add(moduleTreeNode(module, qxModuleList));
			}
		}
		return jsonArray;
	}

	// 模块树树节点
	private JSONObject moduleTreeNode(QxModule module, List<QxModule> qxModuleList) {
		JSONObject json = new JSONObject();
		json.put("data", module.getName());
		JSONObject attributes = new JSONObject();
		attributes.put("id", module.getId());
		attributes.put("parentId", module.getParentId());
		attributes.put("mask", module.getMask());
		attributes.put("name", module.getName());
		attributes.put("moduleURL", module.getPageUrl());
		json.put("attr", attributes);
		// 查找该模块下面的直接子模块
		List<QxModule> childModules = new ArrayList<QxModule>();
		for (QxModule qxModule : qxModuleList) {
			String mask = qxModule.getMask();
			// 存在子角色的话调用自方法递增查询是否有下一级模块
			if (((mask.length() >= 3) && module.getId().equals(qxModule.getParentId()))) {
				childModules.add(qxModule);
			}
		}
		// 同一级的模块封装添加到上一级节点中的children
		if (childModules != null && childModules.size() > 0) {
			json.put("children", moduleChildTreeNode(childModules, qxModuleList));
		}
		return json;

	}

	/**
	 * 查找第一级的最高相同级别的模块
	 * 
	 * @param qxModule
	 * @param qxModules
	 * @return
	 */
	private List<QxModule> findLastSameLevelModules(List<QxModule> qxModules) {
		QxModule qxModule = findTopModule(qxModules); // 找到最顶级模块
		List<QxModule> qxModules2 = new ArrayList<QxModule>();
		for (int i = 0; i < qxModules.size(); i++) {
			if (qxModules.get(i).getLevel() - qxModule.getLevel() == 0) {
				qxModules2.add(qxModules.get(i));
			}
		}
		return qxModules2;
	}

	/**
	 * 找到最顶级模块
	 * 
	 * @param qxModules
	 * @return
	 */
	private QxModule findTopModule(List<QxModule> qxModules) {
		QxModule module = qxModules.get(0);
		Integer level = qxModules.get(0).getLevel();
		;
		for (QxModule qxModule : qxModules) {
			if (qxModule.getLevel() - level < 0) {
				level = qxModule.getLevel();
				module = qxModule;
			}
		}
		return module;
	}

	// /////////////////////////////////////////////////////////生成树数据Json
	// End////////////////////////////////////////////

	@Override
	public List<QxModule> findArrayJonsModuleByUserId(List<String> roleIds) {
		String hql = "from QxModule as m where exists (select 1 from QxModule as module,QxreRoleModule as re where m.id=module.id and re.roleId in (:roleIds) and re.moduleId=module.id and module.active=0 and module.desplay=2 and re.active=0 group by module.id)";
		Finder finder = new Finder(hql);
		finder.setParam("roleIds", roleIds);
		List<QxModule> qxModules = baseDao.queryForList(finder, null);
		return qxModules;
	}

	/**
	 * 根据人员查询部门
	 * 
	 * @param userId
	 * @return @
	 */
	public List<QxModule> findModuleByUserId(Long userId) {
		if (userId == null)
			return null;
		Finder finder = new Finder(sql_all_moduleIds_by_userId, false);
		finder.setParam("userId", userId);
		finder.setParam("userId1", userId);
		List<String> moduleIds = baseDao.queryForList(finder, null);
		if (CollectionUtils.isEmpty(moduleIds))
			return null;
		String hql = "from QxModule as m where id in (:moduleIds) and active=0 and desplay=2";
		finder = new Finder(hql);
		finder.setParam("moduleIds", moduleIds);
		List<QxModule> qxModules = baseDao.queryForList(finder, null);
		return qxModules;
	}

	@Override
	public List<QxModule> findChildrenModuleByModuleId(String moduleId, Integer display) {
		String hql = "";
		Finder finder = new Finder(hql);
		// 为空查询所有的可显示模块信息
		if (StringUtils.isEmpty(moduleId)) {
			hql = "from QxModule where active=0 and desplay=2";
			finder.append(hql);
		} else {// 不为空模糊查询此模块下的所有子模块(包括当前模块)
			QxModule qxModule = findModuleByModuleId(moduleId);
			if (qxModule == null)
				return null;
			hql = "from QxModule where mask like (:mask) and active=0";
			finder.append(hql);
			if (display != null) {
				finder.append(" and desplay=:desplay ");
				finder.setParam("desplay", display);
			}
			finder.setParam("mask", qxModule.getMask() + "%");
		}
		finder.append(" order by mask");
		List<QxModule> qxModules = baseDao.queryForList(finder, null);
		return qxModules;
	}

	@Override
	public QxModule findModuleByModuleId(String moduleId) {
		String hql = "from QxModule where id in (:moduleId) and active=0";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", moduleId);
		QxModule qxModule = baseDao.queryForObject(finder);
		// 查找父模块的名称
		if (qxModule != null) {
			hql = "select name from QxModule where id=:id";
			finder = new Finder(hql);
			finder.setParam("id", qxModule.getParentId());
			String parentName = baseDao.queryForObject(finder);
			if (StringUtils.isNotEmpty(parentName)) {
				qxModule.setParentName(parentName);
			} else {
				qxModule.setParentName("根模块");
			}
		}
		return qxModule;
	}

	@Override
	public boolean deleteModuleNode(String moduleId) {
		String hql = "update QxModule set active=1 where mask like (select mask from QxModule where id = :moduleId)+'%'";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", moduleId);
		Integer num = baseDao.executeUpdate(finder);
		if (num != null && num > 0)
			return true;
		return false;
	}

	@Override
	public boolean updateQxModule(QxModule qxModule) {
		QxModule module = findModuleByModuleId(qxModule.getId());
		module.setName(qxModule.getName());
		module.setAlias(qxModule.getAlias());
		module.setSort(qxModule.getSort());
		module.setPageUrl(qxModule.getPageUrl());
		module.setSubmitUrl(qxModule.getSubmitUrl());
		module.setDesplay(qxModule.getDesplay());
		module.setUpdatePerson(LoginUserUtils.getUserName());
		module.setUpdateTime(new Date());
		baseDao.update(module);
		return true;
	}

	@Override
	public boolean saveQxModule(QxModule qxModule) {
		// 生成新的模块编号
		String mask = createNewModuleMask(qxModule.getParentId(), qxModule.getMask());
		if (StringUtils.isBlank(mask)) {
			mask = findMaxMaskCreateRootMask();
			qxModule.setParentId("-1");
		}
		// 增加模块的属性值
		qxModule.setMask(mask);

		/*
		 * String moduleId = qxModule.getPageUrl() == null ? qxModule
		 * .getSubmitUrl() : qxModule.getPageUrl(); if
		 * (StringUtils.isEmpty(moduleId))
		 */
		String moduleId = UUID.randomUUID().toString().replace("-", "_");
		qxModule.setId(moduleId);
		qxModule.setCreatePerson(LoginUserUtils.getUserName());
		qxModule.setCreateTime(new Date());
		qxModule.setActive(0);
		qxModule.setLevel(mask.length() / 3);
		baseDao.save(qxModule);
		// 修改父模块对应的操作Id
		updateModuleOpers(qxModule.getParentId(), qxModule.getId());
		return true;
	}

	/**
	 * 拖拽后修改拖拽前的父类的操作值
	 * 
	 * @param id
	 * @param oper
	 *            @
	 */
	private void upClearParentMdouleOpers(String id) {
		// 根据模块查找父模块
		String hql = "from QxModule where id = (select parentId from QxModule where id = :moduleId)";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", id);
		QxModule qxModule = baseDao.queryForObject(finder);
		if (qxModule == null || StringUtils.isBlank(qxModule.getOperationIds()))
			return;
		// 移除操作，拼装值
		String opers = "";
		for (String str : Arrays.asList(qxModule.getOperationIds().split(","))) {
			if (str.equals(id))
				continue;
			opers = opers + (str + ",");
		}
		// 修改模块的操作值为拼装后的
		finder = new Finder("update QxModule set operationIds=:operationIds where id = :moduleId");
		finder.setParam("moduleId", qxModule.getId());
		finder.setParam("operationIds", opers.substring(0, opers.length() - 1));
		baseDao.executeUpdate(finder);
	}

	/**
	 * 修改模块的操作Oper
	 * 
	 * @param id
	 * @param oper
	 *            @
	 */
	private void updateModuleOpers(String id, String oper) {
		String hql = "update QxModule set operationIds=operationIds+:operationIds where id = :moduleId";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", id);
		finder.setParam("operationIds", "," + oper);
		baseDao.executeUpdate(finder);
	}

	/**
	 * 根据父模块Id查询子级中同一级别的所有模块，判断模块中间存在没有使用的编号为新编号 如：（001,003,004）就使用002为新的编号
	 * 
	 * @param parentId
	 * @return @
	 */
	private String createNewModuleMask(String parentId, String parentMask) {
		if (StringUtils.isBlank(parentId))
			return null;
		// 根据父模块查询出所有的直接子级模块
		String hql = "select mask from QxModule where parentId = :parentId";
		Finder finder = new Finder(hql);
		finder.setParam("parentId", parentId);
		List<String> maskList = baseDao.queryForList(finder, null);
		// 当同级没有模块时直接返回001节点
		if (CollectionUtils.isEmpty(maskList)) {
			return (parentMask != null ? parentMask : "") + "001";
		}
		// 在1-999直接进行循环，中间有一个在同一级没有使用过就返回要使用的mask
		for (int i = 1; i < 1000; i++) {
			boolean flag = true;
			for (String mask : maskList) {
				if (i - Integer.valueOf(mask.substring(mask.length() - 3)) == 0) {
					flag = false;
					continue;
				}
			}
			if (flag) {
				if (i < 10)
					return (parentMask != null ? parentMask : "") + "00" + i;
				if (10 <= i && i <= 99)
					return (parentMask != null ? parentMask : "") + "0" + i;
				break;
			}
		}
		return null;
	}

	/**
	 * 生成RootMask
	 * 
	 * @return @
	 */
	private String findMaxMaskCreateRootMask() {
		String mask = "001";
		String hql = "select max(mask) from QxModule where parentId='-1'";
		Finder finder = new Finder(hql);
		Object object = baseDao.queryForObject(finder);
		if (object == null)
			return mask;
		mask = (Integer.valueOf(object.toString()) + 1) + "";
		if (mask.length() - 1 == 0)
			mask = "00" + mask;
		else if (mask.length() - 2 == 0)
			mask = "0" + mask;
		return mask;

	}

	@SuppressWarnings("unchecked")
	@Override
	public Map findOpersFieldsByIds(String id) {
		QxModule module = baseDao.findById(QxModule.class, id);
		Map m = new HashMap();
		// oper
		List<QxModule> listOper = findOpers(module.getOperationIds());
		List<String> opers = new ArrayList<String>();
		if (listOper != null && listOper.size() > 0) {
			for (QxModule mod : listOper) {
				opers.add(mod.getName());
			}
			m.put("opers", opers);
		}
		return m;
	}

	@Override
	public JSONArray findModuleFieldOperByRoleIds(String moduleId, Integer userId) {
		// 根据用户Id查询对应角色
		List<QxRole> qxRoles = roleService.findRoleByUser(Long.valueOf(userId));
		if (CollectionUtils.isEmpty(qxRoles))
			return null;
		// 储存角色Id的集合
		List<String> roleIds = new ArrayList<String>();
		for (QxRole qxRole : qxRoles) {
			roleIds.add(qxRole.getId());
		}
		String hql = "from QxreRoleModule where roleId in (:roleIds) and moduleId=:moduleId and active=0";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", moduleId);
		finder.setParam("roleIds", roleIds);
		List<QxreRoleModule> reRoleModules = baseDao.queryForList(finder, null);
		if (CollectionUtils.isEmpty(reRoleModules))
			return null;
		JSONArray array = new JSONArray();
		for (QxreRoleModule re : reRoleModules) {
			JSONObject jObject = findFieldOperation(re.getOperationIds(), re.getFieldIds());
			array.add(jObject);
		}
		return array;
	}

	@Override
	public JSONObject findModuleFieldOper(String moduleId, String roleId) {
		if (StringUtils.isNotBlank(roleId) && StringUtils.isNotBlank(moduleId)) {
			String hql = "from QxreRoleModule where roleId=:roleId and moduleId=:moduleId and active=0";
			Finder finder = new Finder(hql);
			finder.setParam("moduleId", moduleId);
			finder.setParam("roleId", roleId);
			QxreRoleModule reRoleModule = baseDao.queryForObject(finder);
			if (reRoleModule == null)
				return null;
			return findFieldOperation(reRoleModule.getOperationIds(), reRoleModule.getFieldIds());
		}
		QxModule module = baseDao.findById(QxModule.class,moduleId);
		return findFieldOperation(module.getOperationIds(), module.getFieldIds());
	}

	/**
	 * 查询操作和角色列表
	 * 
	 * @return @
	 */
	public JSONObject findFieldOperation(String operationIds, String fieldIds) {
		JSONObject o = new JSONObject();
		// oper
		List<QxModule> listOper = findOpers(operationIds);
		if (listOper != null && listOper.size() > 0) {
			JSONArray array = new JSONArray();
			for (QxModule mod : listOper) {
				JSONObject json = new JSONObject();
				json.put("alias", mod.getAlias());
				json.put("id", mod.getId());
				array.add(json);
			}
			o.put("opers", array);
		}
		return o;
	}

	// 查询模块下的操作信息
	@Override
	public List<QxModule> findOpers(String operationIds) {
		if (StringUtils.isBlank(operationIds))
			return null;
		String[] opers = operationIds.split(",");
		if (opers == null || opers.length == 0)
			return null;
		List<String> listOperId = Arrays.asList(opers);
		Finder finder = new Finder(" from QxModule  where active=0 and id in (:ids)");
		finder.setParam("ids", listOperId);
		return baseDao.queryForList(finder, null);
	}


	@Override
	public List<String> findModuleQxList(String moduleId) {
		// 查询出相应的操作权限Id
		String hql = "select operationIds from QxModule where id = :moduleId and active = 0 ";
		Finder finder = new Finder(hql);
		finder.setParam("moduleId", moduleId);
		String operationIds = baseDao.queryForObject(finder);
		if (StringUtils.isBlank(operationIds))
			return null;
		// 根据操作Id查询相应的操作名称
		List<String> list = findModuleQxByOpers(operationIds);
		return list;
	}

	/**
	 * 根据操作Id查询相应的操作名称
	 * 
	 * @param opers
	 *            操作Id集合
	 * @return @
	 */
	private List<String> findModuleQxByOpers(String opers) {
		//
		String hql = "select name from QxModule where id in (:moduleIds) and active = 0 ";
		Finder finder = new Finder(hql);
		finder.setParam("moduleIds", Arrays.asList(opers.split(",")));
		List<String> list = baseDao.queryForList(finder, null);
		return list;
	}



	@Override
	public void updateModuoeByMoveNode(QxModule module) {
		// 修改拖拽前的操作列Opers
		upClearParentMdouleOpers(module.getId());
		// 生成新的模块编号
		String mask = createNewModuleMask(module.getParentId(), module.getMask());
		if (mask == null) {
			mask = findMaxMaskCreateRootMask();
		}

		String hql = "update QxModule set parentId=:parentId,mask=:mask,level=:level where id=:id";
		Finder finder = new Finder(hql);
		finder.setParam("id", module.getId());
		finder.setParam("mask", mask);
		finder.setParam("parentId", module.getParentId());
		finder.setParam("level", mask.length() / 3);
		baseDao.executeUpdate(finder); // 修改编号
		updateModuleMaskByParentId(module.getId(), mask, mask.length() / 3); // 修改当前模块下的子模块mask
		updateModuleOpers(module.getParentId(), module.getId());// 修改拖拽后的操作列Opers
	}

	/**
	 * 把字符串根据符号转换成List集合
	 * 
	 * @param context
	 *            文本
	 * @param symbol
	 *            符号
	 * @return
	 */
	private List<String> convertListByStr(String context, String symbol) {
		if (StringUtils.isBlank(context))
			return null;
		List<String> list = new ArrayList<String>();
		String[] strs = context.split(symbol);
		for (int i = 0; i < strs.length; i++) {
			list.add(strs[i]);
		}
		return list;
	}

	/**
	 * 根据模块Id修改此模块下的子模块中所有的mask
	 * 
	 * @
	 */
	private void updateModuleMaskByParentId(String parentId, String mask, Integer level) {
		// 查询此模块下是否存在子模块
		String hql = "from QxModule where parentId = :parentId";
		Finder finder = new Finder(hql);
		finder.setParam("parentId", parentId);
		List<QxModule> list = baseDao.queryForList(finder, null);
		if (CollectionUtils.isEmpty(list)) {
			for (QxModule qx : list) {
				String value = qx.getMask().length() > 3 ? qx.getMask().substring(qx.getMask().length() - 3) : qx
						.getMask();
				String createMask = mask + value;
				qx.setMask(createMask);
				qx.setLevel(createMask.length() / 3);
				baseDao.update(qx);
				// 递归判断当前模块是否还存在自己节点
				updateModuleMaskByParentId(qx.getId(), qx.getMask(), qx.getLevel());
			}
		} else {
			return;
		}
	}

	@Override
	public List<QxModule> findQxModuleByParentId() {
		String hql = "from QxModule where parentId='-1' and active=0";
		Finder finder = new Finder(hql);
		List<QxModule> modules = baseDao.queryForList(finder, null);
		return modules;
	}

	@Override
	public QxModule findQxModuleByUrl(String pageUrl) {
		String hql = " From QxModule Where active=0 and pageUrl=:pageUrl";
		Finder finder = new Finder(hql);
		finder.setParam("pageUrl", pageUrl);
		QxModule model = baseDao.queryForObject(finder);
		return model;
	}

	@Override
	public Boolean isHaveRole(Integer userId, String moduleName) {
		String hql = "select COUNT(*) from [User] as u " + " inner join qxre_user_role as ru on u.ID=ru.userId "
				+ " inner join qxre_role_module as rm on rm.roleId=ru.roleId "
				+ " inner join qx_module as m on m.id=rm.moduleId "
				+ " where u.ID=:userId and m.name=:moduleName and u.active=0 and m.active=0";
		Finder finder = new Finder(hql, false);
		finder.setParam("userId", userId);
		finder.setParam("moduleName", moduleName);
		Object o = baseDao.queryForObject(finder);
		if (o == null) {
			return false;
		} else {
			return Integer.valueOf(o.toString()) == 0 ? false : true;
		}
	}
}
